package com.gitee.qdbp.general.system.biz.permission.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.base.model.consts.Keys;
import com.gitee.qdbp.general.system.api.permission.model.ResourceCascadeBean;
import com.gitee.qdbp.general.system.api.permission.model.ResourceCoreBean;
import com.gitee.qdbp.general.system.api.permission.service.IResourceCascadeQueryer;

/**
 * 权限资源层级业务接口
 *
 * @author zhaohuihua
 * @version 170505
 */
@Service
@Transactional(readOnly = true)
public class ResourceCascadeQueryer implements IResourceCascadeQueryer {

    /** 日志对象 **/
    private static final Logger log = LoggerFactory.getLogger(ResourceCascadeQueryer.class);

    /** {@inheritDoc} **/
    @Override
    public <T extends ResourceCoreBean> ResourceCascadeBean wrap(List<T> list, boolean upgrade) throws ServiceException {
        ResourceCascadeBean root = new ResourceCascadeBean();
        root.setId(Keys.ROOT_CODE);
        root.setName("RootNode");
        wrap(root, list, upgrade);
        return root;
    }

    /** {@inheritDoc} **/
    @Override
    public <T extends ResourceCoreBean> void wrap(ResourceCascadeBean root, List<T> list, boolean upgrade) throws ServiceException {

        List<ResourceCascadeBean> all = new ArrayList<>();
        // id - ResourceCascadeBean
        Map<String, ResourceCascadeBean> map = new HashMap<>();
        map.put(Keys.ROOT_CODE, root); // 根节点

        for (ResourceCoreBean resource : list) {
            ResourceCascadeBean item = resource.to(ResourceCascadeBean.class);
            if (resource instanceof ResourceCascadeBean) {
                ResourceCascadeBean o = (ResourceCascadeBean) resource;
                item.setChildren(o.getChildren());
            }
            all.add(item);
            map.put(resource.getId(), item);
        }

        List<String> lost = new ArrayList<>(); // 未找到上级的权限资源的KEY
        for (ResourceCascadeBean item : all) {
            String pid = item.getParentId();
            if (map.containsKey(pid)) {
                map.get(pid).addChild(item);
            } else {
                lost.add(item.getKey());
                if (upgrade) {
                    root.addChild(item);
                }
            }
        }

        if (!lost.isEmpty()) {
            log.trace("Node's parent not exist, upgrade={}: {}", upgrade, lost.toString());
        }

    }

}
